﻿using System;
using Flagwind.Services;
using Flagwind.Resources;

namespace Flagwind.Options.Commands
{
	public class OptionsCommand : CommandBase<CommandContext>
	{
		#region 成员字段

		private IOptionProvider _options;

		#endregion

		#region 构造方法

		public OptionsCommand() : base("Options")
		{
			_options = Flagwind.ComponentModel.ApplicationContextBase.Current.OptionManager;
		}

		public OptionsCommand(string name) : base(name)
		{
			_options = Flagwind.ComponentModel.ApplicationContextBase.Current.OptionManager;
		}

		#endregion

		#region 公共属性

		public IOptionProvider Options
		{
			get
			{
				return _options;
			}
			set
			{
				if(value == null)
				{
					throw new ArgumentNullException();
				}

				_options = value;
			}
		}

		#endregion

		#region 执行方法

		protected override object OnExecute(CommandContext context)
		{
			var manager = _options as OptionManager;

			if(manager != null)
			{
				this.Print(context.Output, manager.RootNode, 0);
			}

			return _options;
		}

		#endregion

		#region 私有方法

		private void Print(ICommandOutlet output, OptionNode node, int depth)
		{
			if(node == null)
			{
				return;
			}

			output.Write(CommandOutletColor.DarkYellow, (depth > 0 ? new string('\t', depth) : string.Empty) + node.Name);

			if(string.IsNullOrWhiteSpace(node.Title))
			{
				output.WriteLine();
			}
			else
			{
				output.WriteLine(CommandOutletColor.DarkGray, " [{0}]", node.Title);
			}

			if(node.Option != null && node.Option.OptionObject != null)
			{
				output.WriteLine(Flagwind.Runtime.Serialization.Serializer.Text.Serialize(node.Option.OptionObject));
			}

			foreach(var child in node.Children)
			{
				Print(output, child, depth + 1);
			}
		}

		#endregion

		#region 静态方法

		internal static IOptionProvider GetOptionProvider(CommandTreeNode node)
		{
			if(node == null)
			{
				return null;
			}

			var command = node.Command as OptionsCommand;

			if(command != null)
			{
				return command.Options;
			}

			return GetOptionProvider(node.Parent);
		}

		#endregion
	}
}